package de.tabuma.shopping.logik;

import de.tabuma.shopping.entity.*;
import de.tabuma.shopping.logik.*;
import java.io.*;
import java.util.logging.*;
import java.util.*;
import java.net.*;
import java.io.*;
import de.tabuma.lib.*;

/**
 *
 * @author $Author: alefen $
 * @version $Revision: 1.1.1.1.4.1 $
 * @since $Date: 2010/01/13 10:22:52 $
 */
public class PayPalFacade {

    private static java.util.logging.Logger log = Logger.getLogger(PayPalFacade.class.getName());
    private static final String ENCODING_TYPE = "UTF-8";

    private static String doEncodeAndReturnAsParamString(HashMap<String,String> param) {
        String paramStr = "";
        Set<String> keys = param.keySet();
        Iterator<String> myIt = keys.iterator();
        boolean notfirst = false;
        try {
            while(myIt.hasNext()) {
                String key = myIt.next();
                String value = URLEncoder.encode(param.get(key),ENCODING_TYPE);
                if(notfirst) {
                    paramStr += "&";
                }
                notfirst = true;
                paramStr += key + "=" +value;
            }
        }
        catch(Exception e) {
            log.warning(e.getMessage());
        }
        return paramStr;
    }

    private static String doConnection(HashMap<String,String> param,String urlStr) {
        String connectionStr = "";
        try {
            log.warning(urlStr);
            URL url = new URL(urlStr);
            URLConnection conn = url.openConnection();

            conn.setRequestProperty("User-Agent","Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)");
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);
            conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            DataOutputStream printout = new DataOutputStream(conn.getOutputStream());

            log.fine("Fill request with parameter.");
            String paramStr = doEncodeAndReturnAsParamString(param);
            printout.writeBytes(paramStr);
            printout.flush();
            printout.close();

            log.warning("Parameter:"+param);

            log.fine("Start connection");
            conn.connect();

            Map headers = conn.getHeaderFields();
            Iterator it = headers.keySet().iterator();
            while (it.hasNext()) {
              String key = (String)it.next();
              log.fine(key+": "+headers.get(key));
            }
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line=null;
            while ((line=in.readLine()) != null) {
              connectionStr += line;
            }
            log.warning("conn:"+connectionStr);
        }
        catch(Exception e) {
            log.warning(e.getMessage());
        }
        return connectionStr;
    }

    public static String getPayPalGetExpressCheckoutDetails(String token,int orderID) {
        String payerID = null;
        try {
            String payPalUrl = de.tabuma.shopping.constants.payPalAuthentificationURL;
            HashMap<String,String> param = new HashMap<String,String>();
            param.put("USER", de.tabuma.shopping.constants.payPalUser);
            param.put("PWD", de.tabuma.shopping.constants.payPalPassword);
            param.put("SIGNATURE", de.tabuma.shopping.constants.payPalSignature);
            param.put("VERSION", "2.3");
            param.put("TOKEN", token);
            param.put("METHOD", "GetExpressCheckoutDetails");

            log.fine("Giving focus to doConnection with params param:"+param+"; url:"+payPalUrl);
            String responseStr = doConnection(param, payPalUrl);

            if(responseStr.indexOf("ACK=Success")!=-1) {
                String searchStr = "PAYERID=";
                int indexOf = responseStr.indexOf("PAYERID=");
                int indexOf1 = responseStr.indexOf("&",indexOf);
                payerID = responseStr.substring(indexOf+searchStr.length(),indexOf1);
                log.fine("responseStr:"+responseStr);
                log.fine("payerID:"+payerID);
            }
            else {
                log.fine("responseStr:"+responseStr);
            }
        }
        catch(Exception e) {
            log.warning(e.getMessage());
        }
        return payerID;
    }

    public static boolean getPayPalDoExpressCheckout(String token,String payerID,int orderID, LicensePackageFacade licensePackageFacade) {
        boolean success = false;
        try {

            String payPalUrl = de.tabuma.shopping.constants.payPalAuthentificationURL;
            HashMap<String,String> param = new HashMap<String,String>();
            param.put("USER", de.tabuma.shopping.constants.payPalUser);
            param.put("PWD", de.tabuma.shopping.constants.payPalPassword);
            param.put("SIGNATURE", de.tabuma.shopping.constants.payPalSignature);
            param.put("VERSION","2.3");
            param.put("PAYMENTACTION", "Authorization");
            param.put("PAYERID",payerID);
            param.put("TOKEN",token);
            param.put("METHOD","DoExpressCheckoutPayment");
            double price = OrderFacade.getPriceOfOrder(orderID, licensePackageFacade);
            param.put("AMT", ""+((double)Math.round(price*100))/100.0);
            param.put("CURRENCYCODE","EUR");

            log.fine("Giving focus to doConnection with params param:"+param+"; url:"+payPalUrl);
            String responseStr = doConnection(param, payPalUrl);

            if(responseStr.indexOf("ACK=Success")!=-1) {
                success = true;
            }
            else {
                success = false;
            }

        }
        catch(Exception e) {
            log.warning(e.getMessage());
            return false;
        }

        return success;
    }

    public static String getPayPalTokenSetExpressCheckout(Order myOrder, Hashtable parameter, String orderNav, LicensePackageFacade licensePackageFacade,String servlet, String url) {
        String errorRequestParam = orderNav+"="+de.tabuma.shopping.constants.ORDERNAV_ERRORPAYMENT;
        String orderVerificationRequestParam = orderNav+"="+de.tabuma.shopping.constants.ORDERNAV_VERIFICATIONPAYMENT;
        String orderTokenRequestParam = de.tabuma.shopping.constants.ORDER_TOKEN+"="+myOrder.getToken();

        String errorUrl = url+servlet;
        errorUrl += "?"+view.getLinkAsAttribute(parameter)+"&"+errorRequestParam;

        String successUrl = url+servlet;
        successUrl += "?"+view.getLinkAsAttribute(parameter)+"&"+orderVerificationRequestParam+"&"+orderTokenRequestParam;

        try {
            log.fine("Initialising request parameter.");

            String payPalUrl = de.tabuma.shopping.constants.payPalAuthentificationURL;
            HashMap<String,String> param = new HashMap<String,String>();
            param.put("USER", de.tabuma.shopping.constants.payPalUser);
            param.put("PWD", de.tabuma.shopping.constants.payPalPassword);
            param.put("SIGNATURE", de.tabuma.shopping.constants.payPalSignature);
            param.put("VERSION","2.3");
            param.put("PAYMENTACTION", "Authorization");
            double price = ((double) Math.round(OrderFacade.getPriceOfOrder(myOrder.getId().intValue(),licensePackageFacade)*100))/100.0;
            param.put("AMT", ""+price);
            param.put("RETURNURL",successUrl);
            param.put("CANCELURL",errorUrl);
            param.put("METHOD","SetExpressCheckout");
            param.put("NOSHIPPING","1");
            param.put("CURRENCYCODE","EUR");
            param.put("HDRIMG",de.tabuma.shopping.constants.imageUrl);

            log.fine("Initialising url "+payPalUrl);
            log.fine("Giving focus to doConnection with params param:"+param+"; url:"+payPalUrl);
            String responseStr = doConnection(param, payPalUrl);

            
            String args[] = responseStr.split("&");
            if(args!=null) {
                for(int i=0;i<args.length;i++) {
                    String split[] = args[i].split("=");
                    if(split[0].equals("TOKEN")) {
                        String token = URLDecoder.decode(split[1],ENCODING_TYPE);
                        log.fine("TOKEN:"+token);
                        return token;
                    }
                }
            }
        }
        catch(Exception e) {
            log.warning(e.getMessage());
        }
        return null;
    }
}
